package user

import (
	"vblog/common"

	"github.com/rs/xid"
	"golang.org/x/crypto/bcrypt"
)

type User struct {
	*common.Meta
	*CreateUserReuqest
}

type CreateUserReuqest struct {
	Username string `validate:"required"`
	Password string `validate:"required"`
}

func (r *CreateUserReuqest) Validate() error {
	return common.Validate(r)
}

func (t *User) TableName() string {
	return "users"
}

func NewToken(username string) *Token {
	return &Token{
		Meta:     common.NewMeta(),
		Username: username,
		// 随机字符串,没有任何含义
		AccessToken: xid.New().String(),
	}
}

type Token struct {
	*common.Meta
	// JWT
	AccessToken string `json:"token"`
	// 用户名称
	Username string `json:"username"`
}

func (t *Token) String() string {
	return common.ToJSON(t)
}

func (t *Token) TableName() string {
	return "tokens"
}

func NewDefaultUser() *User {
	return NewUser(NewCreateUserRequest())
}

func NewUser(req *CreateUserReuqest) *User {
	return &User{
		Meta:              common.NewMeta(),
		CreateUserReuqest: req,
	}
}

func (u *User) CheckPassword(planPassword string) error {
	return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(planPassword))
}

func NewCreateUserRequest() *CreateUserReuqest {
	return &CreateUserReuqest{}
}

func (u *User) String() string {
	return common.ToJSON(u)
}

// 将明文密码变成一个Hash
// 密码 ---> hash 是一一对应的,
// 生产不会使用这种方式.

// func (u *User) BuildHashedPassword() error {
// 	h := sha1.New()
// 	_, err := h.Write([]byte(u.Password))
// 	if err != nil {
// 		return err
// 	}
// 	hd := h.Sum(nil)
// 	// base64 编码, []byte是一个二进制数据, 不一定可以转换成字符串
// 	u.Password = base64.StdEncoding.EncodeToString(hd)
// 	return nil
// }

// v2 版本
func (u *User) BuildHashedPassword() error {
	// 专门用于Password hash的方法
	hp, err := bcrypt.GenerateFromPassword([]byte(u.Password), 10)
	if err != nil {
		return err
	}
	u.Password = string(hp)
	return nil
}
